package com.itheima.health.security;

import com.alibaba.fastjson.JSON;
import com.itheima.health.dao.UserDao;
import com.itheima.health.entity.Result;
import com.itheima.health.pojo.Permission;
import com.itheima.health.pojo.Role;
import com.itheima.health.pojo.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.AntPathMatcher;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author ：石破天
 * @date ：Created in 2022/6/3
 * @description ：权限过滤器
 * @version: 1.0
 */
@Slf4j
@WebFilter(urlPatterns = "/*")
public class HealthSecurityFilter implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        //拦截所有请求
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        // 1.获取URI
        String uri = request.getRequestURI();
        log.info("[权限检查过滤器...],当前uri:{}", uri);
//			filterChain.doFilter(request,response);
        boolean noNeedLogin = checkURI(uri);
        if (noNeedLogin) {
            log.info("该路径是白名单，可以直接方形，无需登录访问");
            //返回结果是true 说明不需要登录 直接可访问 不用拦截
            filterChain.doFilter(request, response);
            return;
        }
        //从域中得到登录的用户
        User user = (User) request.getSession().getAttribute("user");

        //判断用户是否为空
        if (user != null) {
            //用户不为空说明用户已经登录了
            //创建一个方法用来判断请求路径和map中键对应的情况下，user权限表中的权限关键字和map中的值是否相等
            Boolean loginAuthURI = checkLoginAuthURI(uri, user);

            if (loginAuthURI) {
                //返回的是true 说明是对应的 即可访问
                filterChain.doFilter(request, response);


            } else {
                //返回结果为false 说明没有权限
                response.setContentType("application/json;charset=utf-8");
                Result result = new Result(false, "没有访问权限");
                String s = JSON.toJSONString(result);
                response.getWriter().write(s);
            }

        } else {
            //用户为空说明还没有登录 返回重新登录
            response.setContentType("application/json;charset=utf-8");
            Result result = new Result(false, "重新登录");
            String s = JSON.toJSONString(result);
            response.getWriter().write(s);

        }

    }

    @Autowired
    private UserDao userDao;

    private Boolean checkLoginAuthURI(String uri, User user) {
        AntPathMatcher mather = new AntPathMatcher();

        //根据路径具备的权限 把路径里的关键字拿出来
        String currKeyUrl = null;//用它来接收 匹配出来的路径规则

        Set<String> keySet = initAutlUrlMap.keySet();
        for (String keyUri : keySet) {
            if (mather.match(keyUri, uri)) {
                currKeyUrl = keyUri;
            }
        }

        if (currKeyUrl == null) {
            //不需要权限可以直接访问，可以直接访问
            log.info("当前访问路径，不需要权限校验，谁登陆都有权限");
            return true;
        }
        Integer userId = user.getId();
        List<String> permissionList = userDao.selectByidAndPermission(userId);

        //如果到了这里就说明 访问的这个路径需要授权 取出关键字
        String authKeyword = initAutlUrlMap.get(currKeyUrl);
        log.info("改玲竣工需要权限访问，且访问权限关键字是：" + authKeyword);

        //查询到用户的所有权限 拿出用户权限的关键字
        //进行对比
        for (String permission : permissionList) {
            if (authKeyword.equals(permission)) {
                log.info("当前用户权限匹配上了，允许访问");
                return true;
            }
        }

        //如果到了这里就说明他没有访问权限
        return false;
    }


    private boolean checkURI(String uri) {
        //判断一个这个 reqUri 是不是白名单数据
        //创建一个路径匹配器
        AntPathMatcher pathMatcher = new AntPathMatcher();
        //遍历数组
        //url 白名单规则 reqUri 请求的路径
        for (String url : auths) {
            if (pathMatcher.match(url, uri)) {
                log.info("[权限过滤器，匹配是白名单:uri:{}]", uri);
                return true;
            }

        }
    return false;//需要登录访问
    }


    //白名单 不需要登录就可以访问的
    private String[] auths = new String[]{
            "/user/login",
            "/user/logout",
            "/common/**",
            "/mobile/**"
    };


    //创建一个map集合 用来存放相对应的数据
    //键 访问的路径
    //值 查询用户表查出来的路径关键字
    private HashMap<String, String> initAutlUrlMap = new HashMap<>();
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        initAutlUrlMap();
        //权限初始化
    }



    private void initAutlUrlMap() {
        initAutlUrlMap.put("/checkgroup/add", "CHECKGROUP_ADD");
        initAutlUrlMap.put("/checkgroup/deleteCheckGroupitemById", "CHECKGROUP_DELETE");
        initAutlUrlMap.put("/checkgroup/edit", "CHECKGROUP_EDIT");
        initAutlUrlMap.put("/checkgroup/findCheckItemIdsByCheckGroupId", "CHECKGROUP_EDIT");
        initAutlUrlMap.put("/checkgroup/findById", "CHECKGROUP_EDIT");
        initAutlUrlMap.put("/checkgroup/findPage", "CHECKGROUP_QUERY");
        initAutlUrlMap.put("/checkitem/add", "CHECKITEM_ADD");
        initAutlUrlMap.put("/checkitem/delete", "CHECKITEM_DELETE");
        initAutlUrlMap.put("/checkitem/edit", "CHECKITEM_EDIT");
        initAutlUrlMap.put("/checkitem/findById", "CHECKITEM_EDIT");
        initAutlUrlMap.put("/checkitem/findPage", "CHECKITEM_QUERY");
        initAutlUrlMap.put("/setmeal/add", "SETMEAL_ADD");
        initAutlUrlMap.put("/setmeal/delete", "SETMEAL_DELETE");
        initAutlUrlMap.put("/setmeal/edit", "SETMEAL_EDIT");
        initAutlUrlMap.put("/setmeal/findPage", "SETMEAL_QUERY");

//    initAutlUrlMap.put("/","MENU_ADD");
//    initAutlUrlMap.put("/","MENU_DELETE");
//    initAutlUrlMap.put("/","MENU_EDIT");
//    initAutlUrlMap.put("/","MENU_QUERY");
//    initAutlUrlMap.put("/","ORDERSETTING");
        initAutlUrlMap.put("/report/**", "REPORT_VIEW");
//    initAutlUrlMap.put("/","ROLE_ADD");
//    initAutlUrlMap.put("/","ROLE_DELETE");
//    initAutlUrlMap.put("/","ROLE_EDIT");
//    initAutlUrlMap.put("/","ROLE_QUERY");
//    initAutlUrlMap.put("/","USER_ADD");
//    initAutlUrlMap.put("/","USER_DELETE");
//    initAutlUrlMap.put("/","USER_EDIT");
//    initAutlUrlMap.put("/","USER_QUERY");
    }



    @Override
    public void destroy() {

    }

}